#!/usr/bin/python
# coding: utf-8

"""
提示：在爬取每一个页面的额过程中，发现有些页面的应用已经被删除了，并不能进行爬取，开始没有发现这个坑点，一直以为是ip被禁了，
针对于这样的网页，循环爬取3次，如果3次爬取结束并没有获取到数据的话，则认为当前页面对应的应用已经删除，直接从数据库中删除即可
"""

import sys
sys.path.append("..")

import time
import lxml.html
import random
from MySql_InterFace.AppMySql import ApplicationMySql
from MySql_InterFace.GetProxy import GetProxies
from Logging.AppLogging import log_Main
from Downloader.AppDownloader import DownloaderPageHtml
from Config.Config import USER_AGENTS, TimeSleep, CONTENT, MAX_NUM
from SendEmail.SendEmail import SendMain

class Application(object):
    def __init__(self):
        self.app = ApplicationMySql()
        self.urls = self.app.GetUrl()
        self.app.CreateSoftSurvey()
        self.app.CreateSoftInfo()
        self.app_urls = self.app.SelectUrl()
        # print self.app_urls
        self.proxies = GetProxies().getIPUrl()

    def AppUrl(self):
        log_Main(u"对爬取到的每一个网页进行下载", "info")
        print u"总共%d个链接" % len(self.urls)
        for num, url in enumerate(self.urls):
            print u"正在爬取第%d个链接" % (num + 1)
            self.url = url[0]
            x = (self.url, ) # 转化为元组，因为从数据库中获取的数据都是元素
            if x in self.app_urls:
                print u"当前网页已经爬取过，不需要再进行爬取"
                continue
            self.name = url[1]
            # 下载网页
            # 要将args放在kwargs之前，不然会报SyntaxError: non-keyword arg after keyword arg
            self.html = DownloaderPageHtml(url[0], USER_AGENTS[random.randint(0, len(USER_AGENTS) - 1)]).Downloader(MAX_NUM)
            # 对网页进行解析
            self.AppAnalysis()

            # 此时证明当前的这个页面并没有指定的应用，所以直接从数据库中进行删除
            if self.html is None:
                print u"当前url中的应用已经被删除"
                self.app.DeletePageUrl(self.url)

    def AppAnalysis(self):
        tree = lxml.html.fromstring(self.html)
        try:
            print self.url
            tree1 = tree.cssselect("div.app-msg > div.app-detail > div.msg")[0]
            self.comment = tree1.cssselect("span")[0].text_content()
            print self.comment

            tree2 = tree.cssselect("div.detail-app-other-info > ul > li > span")
            self.info = u""
            for x in range(0, len(tree2)):
                self.info += tree2[x].text_content()
                if x == len(tree2) - 1:
                    self.info += u'。'
                else:
                    self.info += u"，"
            print self.info

            # 存储到数据库中
            self.app.InsertSoftSurvery((self.url, self.name, self.comment, self.info))

            tree3 = tree.cssselect("div.detail-app-intro > div.main-right > div.other-info > div")[0]
            # 获取软件的基本信息
            self.Info = []
            for r in tree3.cssselect("p")[1:]:
                self.Info.append(r.text_content())
            print self.Info

            text = tree3.cssselect("a#checkPermissions")[0].text_content()
            # print text

            self.jurisdiction = u""
            tree4 = tree3.cssselect("div > ul.permissions-list > li")
            for x in range(len(tree4)):
                self.jurisdiction += tree4[x].text_content()
                if x == len(tree4) - 1:
                    self.jurisdiction += u'。'
                else :
                    self.jurisdiction += u'，'
            print self.jurisdiction
            self.app.InsertSoftInfo((self.url, self.name, self.Info[0], self.Info[1], self.Info[2], self.Info[3], self.Info[4], self.Info[5], self.jurisdiction))
            log_Main(u"本次存储成功！！！！", "info")
        except Exception as e:
            log_Main(e, "error")
            print e
            # 如果发送list index out of range，则证明list访问的时候越界，但是针对于每一个正常的网页来说根本不可能发生这种情况，所以此时是爬取网页的时候IP被禁
            print u"IP被禁，循环爬取，直到IP可以使用"
            # 获取此时网页的长度
            if self.html is not None:
                len1 = len(self.html)
            else :
                len1 = 0

            # time.sleep(TimeSleep)
            # 不可以的话，使用代理ip进行爬取
            if len(self.proxies) <= 0:
                self.get_proxies()
            proxy= self.proxies[random.randint(0, len(self.proxies) - 1)]
            print u"当前使用的代理IP为：", proxy
            # proxies 设置代理ip，timeout设置超时时间（以秒为单位）
            # 一个代理尝试使用一次，如果不能使用它获取到网页，则可以断定此ip不能使用
            self.html = DownloaderPageHtml(self.url, USER_AGENTS[random.randint(0, len(USER_AGENTS) - 1)]).Downloader(MAX_NUM, proxies= proxy, timeout= 3)
            # 使用代理ip进行爬取的情况
            if  self.html is not None and len(self.html) != len1:
                print u"代理IP可以使用"
                try:
                    # 当下面代码运行没有错误的时候，则可以获取数据，进行保存
                    tree = lxml.html.fromstring(self.html)
                    t = tree.cssselect("div.detail-app-intro > div.main-right > div.other-info > div")[0]
                    self.AppAnalysis()
                except Exception as e:
                    pass

            else:
                # 此代理ip不能使用
                print u"此代理ip不能使用，从ip池中删除"
                # 由于代理ip的数据库每次用的时候都会删除，然后再创建，所以此时没有必要专门去删除数据库中的字段，保留即可，到下面代码中会重建数据库
                self.proxies.remove(proxy)
                print u"当前代理ip的数量为：", len(self.proxies)
                # 当没有代理ip的时候再重新获取代理ip即可
                if len(self.proxies) <= 0:
                    self.get_proxies()
            # 查看自己的IP是否可以使用了
            self.html = DownloaderPageHtml(self.url, USER_AGENTS[random.randint(0, len(USER_AGENTS) - 1)]).Downloader( MAX_NUM)
            # 此时证明网页在原来错误的基础上又发生了变化，继续对网页进行解析，查看是否正确即可
            if self.html is not None and len(self.html) != len1:
                try:
                    # 当下面代码运行没有错误的时候，则可以获取数据，进行保存
                    tree = lxml.html.fromstring(self.html)
                    t = tree.cssselect("div.detail-app-intro > div.main-right > div.other-info > div")[0]
                    self.AppAnalysis()
                except Exception as e:
                    pass
            else:
                print u"本机ip还是不能使用"
                self.html = None
                return

    def get_proxies(self):
        from ProxyManager.ProxyManager import ProxyAnalysis
        p = ProxyAnalysis()
        p.ProxyMain()
        # 不能关闭，否则在下面运行的时候会报InterfaceError (0, '')
        # p.Close()
        # 再次获取代理ip
        print u"再次获取代理ip"
        self.proxies = GetProxies().getIPUrl()
        print u"重新获取后代理ip的数量为：", len(self.proxies)
        from SendEmail.SendEmail import SendMain
        SendMain(CONTENT)

if __name__ == "__main__":
    t1 = time.time()
    print u"当前时间为：", time.ctime(t1)
    app = Application()
    app.AppUrl()
    t2 = time.time()
    print u"爬取结束的时间为：", time.ctime(t1)
    print u"花费时间为：%s" % (t2 - t1)
    log_Main("花费时间为:%s" % (t2 - t1), "info")
    SendMain("每个网页的内容爬取完成！！！！")